using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Particle_Editor
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        public SpriteBatch spriteBatch;
        public ContentManager content;
        private IntPtr Surface;
        
        //For measuring the framerate
        int FrameCounter = 0;
        TimeSpan elapsedTime = TimeSpan.Zero;

        public static string theText;
        public static float CurrentFPS = 0;
        public static Random randomizer;

        //Used for reseting the particle system
        public static bool ResetParticles = false;

        //Used for loading custom textures
        public static bool UsingExternalTexture = false;
        public static string ExternalTextureFileName;

        //Used for the emitter pulses
        public static float EmitterSpawnRate = 0.2f;

        //Current Particle System properties
        public static float MinParticleSpeed;
        public static float MaxParticleSpeed;
        public static float MinParticleAcceleration;
        public static float MaxParticleAcceleration;
        public static float MinParticleLifetime;
        public static float MaxParticleLifetime;
        public static float MinParticleScale;
        public static float MaxParticleScale;
        public static int MinNumberOfParticles;
        public static int MaxNumberOfParticles;
        public static float MinParticleRotationSpeed;
        public static float MaxParticleRotationSpeed;
        public static int ParticleColorR = 1;
        public static int ParticleColorG = 1;
        public static int ParticleColorB = 1;
        public static float MinimumParticleAngle = 0;
        public static float MaximumParticleAngle = 100;
        public static int TotalParticlesCreated = 0;
        public static int TotalParticlesDestroyed = 0;
        public static double TimeElapsedSinceStart = 0;
        public static string CurrentParticleTexture;
        Vector2 DirectionIndicator = new Vector2(0, 0);
        //Texture2D DirectionHelper;
        float puffTime = 0.0f;
        public static float AverageDirection = 0;
        

        public static Vector2 EmitterLocation;

        Particles.SmokeEffect smoke;
        public Game1(IntPtr Surface)
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            this.Surface = Surface;

            graphics.PreparingDeviceSettings += new EventHandler<PreparingDeviceSettingsEventArgs>(graphics_PreparingDeviceSettings);
            System.Windows.Forms.Control.FromHandle((this.Window.Handle)).VisibleChanged += new EventHandler(Game1_VisibleChanged);
            randomizer = new Random();
        }

        void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = Surface;
        }   

        void Game1_VisibleChanged(object sender, EventArgs e)
        {
            if (System.Windows.Forms.Control.FromHandle((this.Window.Handle)).Visible == true)
                System.Windows.Forms.Control.FromHandle((this.Window.Handle)).Visible = false;   
     
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here
            content = new ContentManager(Services, "Content");
            smoke = new Particles.SmokeEffect(this, 9);
            this.IsMouseVisible = true;
            

            CurrentParticleTexture = "NoTexture";
            MinParticleSpeed = 20;
            MaxParticleSpeed = 100;

            MinParticleAcceleration = 0;
            MaxParticleAcceleration = 0;

            MinParticleLifetime = 5;
            MaxParticleLifetime = 7;

            MinParticleScale = 0.5f;
            MaxParticleScale = 1.0f;

            MinNumberOfParticles = 7;
            MaxNumberOfParticles = 15;

            MinParticleRotationSpeed = MathHelper.PiOver4 / 2.0f;
            MaxParticleRotationSpeed = MathHelper.PiOver4 / 2.0f;

            Components.Add(smoke);
            //graphics.PreferredBackBufferWidth = 700;
            //graphics.PreferredBackBufferHeight = 510;
            base.Initialize();
            EmitterLocation.X = this.Window.ClientBounds.Width / 2;
            EmitterLocation.Y = this.Window.ClientBounds.Height / 2;
        }
      
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            // TODO: use this.Content to load your game content here
            //DirectionHelper = Content.Load<Texture2D>("Helpers/Indicator");
            
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
            
            base.UnloadContent();
            
      
        }
        public void GetInput(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();
            KeyboardState theKeyboard = Keyboard.GetState();
            if (theKeyboard.IsKeyDown(Keys.Escape))
                this.Exit();

            MouseState theMouse = Mouse.GetState();
            if (theMouse.LeftButton == ButtonState.Pressed)
            {
                if (theMouse.X < this.Window.ClientBounds.Width || theMouse.X > 0)
                {
                    EmitterLocation.X = theMouse.X;// -200;
                }
                if (theMouse.Y < this.Window.ClientBounds.Height || theMouse.Y > 0)
                {
                    EmitterLocation.Y = theMouse.Y;
                }
                
            }
        }
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (ResetParticles == true)
            {
                Components.Remove(smoke);
                smoke.Dispose();
                smoke = new Particles.SmokeEffect(this, 9);
                Components.Add(smoke);
                ResetParticles = false;
            }
            FrameCounter++;

            GetInput(gameTime);
            // TODO: Add your update logic here
            float Delta = (float)gameTime.ElapsedGameTime.TotalSeconds;

            puffTime -= Delta;

            if (puffTime < 0)
            {
                smoke.AddParticles(EmitterLocation);
                puffTime = EmitterSpawnRate;
            }

            elapsedTime += gameTime.ElapsedGameTime;
            if (elapsedTime > TimeSpan.FromSeconds(1))
            {
                elapsedTime -= TimeSpan.FromSeconds(1);
                CurrentFPS = (float)FrameCounter;
                FrameCounter = 0;
            }
            AverageDirection = (MinimumParticleAngle + MaximumParticleAngle) / 2;
            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
        
            GraphicsDevice.Clear(Color.Black);
            TimeElapsedSinceStart = gameTime.TotalGameTime.Seconds;
            spriteBatch.Begin();
            
            //spriteBatch.Draw(DirectionHelper, new Vector2(50, 50), null, Color.White, AverageDirection - 45, new Vector2(DirectionHelper.Width / 2, DirectionHelper.Height / 2), 0.1f, SpriteEffects.None, 0.0f);
            spriteBatch.End();
            // TODO: Add your drawing code here
       
            base.Draw(gameTime);
        }

        public static float GetRandomNumber(float Min, float Max)
        {
            return Min + (float)randomizer.NextDouble() * (Min - Max);
        }
    
    }



}
